home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / chat / reflect.000 / reflect / 3.0b3 / util.c < prev   
Encoding:
C/C++ Source or Header  |  1995-02-06  |  12.2 KB  |  490 lines

  1. /*
  2.  
  3. Copyright 1993, 1994, Cornell University
  4.  
  5. Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose 
  6. and without fee, provided that these copyright and permission notices appear on all copies and 
  7. supporting documentation, the name of Cornell not be used in advertising or publicity pertaining 
  8. to distribution of the program without specific prior permission, notice be given in supporting 
  9. documentation that copying and distribution is by permission of Cornell.  CORNELL MAKES NO 
  10. REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED.  By way of example, but not limitation, 
  11. CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR 
  12. PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, 
  13. TRADEMARKS, OR OTHER RIGHTS.  Cornell shall not be held liable for any liability with respect to 
  14. any claim by the user or any other party arising from use of the program.
  15.  
  16. This material is partially based on work sponsored by the National Science Foundation under Cooperative 
  17. Agreement No. NCR-9318337.  The government has certain rights in this material.
  18.  
  19. */
  20.  
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <varargs.h>
  25. #include <signal.h>
  26. #include <errno.h>
  27. #include <malloc.h>
  28. #include <sys/types.h>
  29. #include <sys/param.h>
  30. #include <sys/ioctl.h>
  31. #include <sys/socket.h>
  32. #include <sys/time.h>
  33.  
  34. #ifndef LINUX
  35. #include <sys/socketvar.h>
  36. #include <net/route.h>
  37. #endif
  38.  
  39. #include <net/if.h>
  40. #include <netinet/in.h>
  41.  
  42. #include "reflect.h"
  43. #include "refmon.h"
  44. #include "globals.h"
  45.  
  46. #define MAXIF 20        /* Maximum number of interfaces expected        */
  47.  
  48. #if     BSD > 43
  49. #define socksize(x)     ((struct sockaddr *)x)->sa_len
  50. #else
  51. #define socksize(x)     sizeof *(x)
  52. #endif
  53.  
  54. void proc_sig()
  55. {
  56.     my_perror("Kill Signal received\n");
  57.     exit(1);
  58. }
  59.  
  60.  
  61. void do_timer()
  62. {
  63.     static short refrefkcnt = 0;
  64.     static short vatinterval = 0;
  65.     static short timeinterval = 0;
  66.     client *ctmp,*ctmp1;
  67.     vat_client *mtmp,*mtmp1;
  68.     struct in_addr   in;
  69.     struct timeval   tp;
  70.     struct timezone  tzp;
  71.     float elapsed;
  72.     short cnt,cnt1;
  73.     char *tmp;
  74.  
  75.     tick_cnt++;
  76.     gettimeofday(&tp, &tzp);
  77.  
  78. #ifndef DONTLOGPKTS
  79.     if ((++timeinterval >= 10) && (chead != NULL))
  80.     {
  81.        tmp = ctime(&tp.tv_sec);
  82.        tmp[24] = ' ';
  83.        dolog("Time: %s   Pkts in %ld   Pkts out %ld   kbits/sec in %d  kbits/sec out %d\n",
  84.              tmp,pkts_in,pkts_out,(short) ((8 * bytes_in)/10240),(short) ((8 * bytes_out)/10240));
  85.        timeinterval = 0;
  86.        pkts_in = pkts_out = bytes_in = bytes_out = 0;
  87.     }
  88. #endif
  89.  
  90.     /* run through the client list */
  91.        
  92.     ctmp = chead;
  93.     while (ctmp != NULL)
  94.     {
  95.        ctmp->clnt_stimer++;
  96.        ctmp->clnt_caploop++;
  97.  
  98.        /* check for cap rate violations */
  99.  
  100.        if ((ctmp->clnt_flags & (CLIENT | NV_UCAST)) && (ctmp->clnt_caploop == TRATE) && (ctmp->clnt_bytecnt != 0))
  101.        {
  102.           elapsed = tp.tv_sec - ctmp->clnt_tp.tv_sec;
  103.           elapsed += (tp.tv_usec/1000000.) - (ctmp->clnt_tp.tv_usec/1000000.);
  104.  
  105. /*
  106.           printf("transmission rate is %f bytes per sec  cap is %d  elapsed is %f\n",
  107.                   (float) ctmp->clnt_bytecnt/elapsed,cap,elapsed);
  108. */
  109.  
  110.           if (ctmp->clnt_bytecnt/elapsed > cap)
  111.           {
  112.              ctmp1 = ctmp;
  113.              ctmp = ctmp->clnt_nptr;
  114.              dolog("client %s is being deleted due to cap rate %f exceeding limit %d\n",
  115.                     ctmp1->clnt_config.name,ctmp1->clnt_bytecnt/elapsed,cap);
  116.  
  117.              if (ctmp->clnt_flags & CLIENT)
  118.                 write_msg(&ctmp1->clnt_addr,kMessageType1,cap_buf);
  119.              tmp_deny(ctmp1->clnt_addr.addr,hold_down);
  120.              hold_down_client(ctmp1);
  121.              continue;
  122.           }
  123.  
  124.           ctmp->clnt_bytecnt = 0;
  125.           ctmp->clnt_caploop = 0;
  126.           ctmp->clnt_tp.tv_sec = tp.tv_sec;
  127.           ctmp->clnt_tp.tv_usec = tp.tv_usec;
  128.        }
  129.  
  130.        /* next check for hold down expirations */
  131.  
  132.        if (ctmp->clnt_flags & HOLD_DOWN)
  133.        {
  134.           if (ctmp->clnt_hdloop++ > HRATE)
  135.           {
  136.              ctmp1 = ctmp;
  137.              ctmp = ctmp->clnt_nptr;
  138.              dolog("client %s hold down has expired and is being deleted\n",ctmp1->clnt_config.name);
  139.              delete_client(ctmp1);
  140.              continue;
  141.           }
  142.        }
  143.  
  144.        /* delete any NV, BCC_CLIENT, or regular clients that have timed out */
  145.  
  146.        if ((ctmp->clnt_flags & (CLIENT | NV_UCLIENT | NV_MCLIENT | BCC_CLIENT)) != 0)
  147.           if ((ctmp->clnt_rtimer++ > TIMEOUT) && ((ctmp->clnt_flags & HOLD_DOWN) == 0))
  148.           {
  149.              ctmp1 = ctmp;
  150.              ctmp = ctmp->clnt_nptr;
  151.              if (ctmp1->clnt_flags & CLIENT)
  152.              {
  153.                 dolog("client timeout -- holding down\n");
  154.                 hold_down_client(ctmp1);
  155.              }
  156.              else
  157.              {
  158.                 if (ctmp1->clnt_flags & BCC_CLIENT)
  159.                    dolog("BCC client timeout -- deleting\n");
  160.                 else
  161.         {
  162.            /* if this nv client is also a vat client, update the vat seq # */
  163.            if ((mtmp = find_vat_client(ctmp1->clnt_addr.addr)) != NULL)
  164.               mtmp->mvn_ocp_seq = ctmp1->clnt_ocp_cnt + ctmp1->clnt_seq + 1;
  165.                    dolog("NV client timeout -- deleting\n");
  166.         }
  167.                 delete_client(ctmp1);
  168.              }
  169.          continue;
  170.           }
  171.  
  172.        /* delete any clients that originated from another reflector that have timed out */
  173.  
  174.        if ((ctmp->clnt_flags & (BCC_ORIGIN | REF1_ORIGIN | REF2_ORIGIN | REF3_ORIGIN))  != 0)
  175.           if (ctmp->clnt_rtimer++ > (2*TIMEOUT))
  176.           {
  177.              ctmp1 = ctmp;
  178.              ctmp = ctmp->clnt_nptr;
  179.              if (ctmp1->clnt_flags & BCC_ORIGIN)
  180.                 dolog("BCC client's client timeout -- deleting\n");
  181.              else
  182.                 dolog("REF client's client timeout -- deleting\n");
  183.              delete_client(ctmp1);
  184.          continue;
  185.           }
  186.  
  187.  
  188.        /* send OCP to our CUSM clients for our NV clients */  
  189.  
  190.        if (ctmp->clnt_flags & (NV_UCLIENT | NV_MCLIENT))
  191.           if (ctmp->clnt_ntimer++ > NV_OCP_TIMER)
  192.           {
  193.              send_nv_ocp(ctmp);
  194.              ctmp->clnt_ntimer = 0;
  195.           }
  196.  
  197.        ctmp = ctmp->clnt_nptr;
  198.     }
  199.  
  200.     /* send keep alive packets to any BCC servers that we have */
  201.  
  202.     if (++refrefkcnt > KALIVE)
  203.     {
  204.        refrefkcnt = 0;
  205.        open_bcc_servers(); 
  206.        open_ucast_ref(); 
  207.     }
  208.  
  209.  
  210.     vatinterval++;
  211.     if (vatinterval == 11)
  212.        vatinterval = 0;
  213.  
  214.     mtmp = mhead;
  215.     while (mtmp != NULL)
  216.     {
  217.       if (mtmp->mvn_rtimer++ > 200) 
  218.       {
  219.          in.s_addr =  mtmp->mvn_addr.addr;
  220.          dolog("Deleting Maven client at %s\n", inet_ntoa(in));
  221.  
  222.          vat_client_cnt--;
  223.  
  224.          if (mtmp == mhead)
  225.          {
  226.             mhead = mtmp->mvn_nptr;
  227.             mtmp1 = mtmp;
  228.             mtmp = mtmp->mvn_nptr;
  229.             free(mtmp1);
  230.          }
  231.          else
  232.          {
  233.             mtmp1 = mhead;
  234.             while (mtmp1->mvn_nptr != mtmp)
  235.                mtmp1 = mtmp1->mvn_nptr;
  236.             mtmp1->mvn_nptr = mtmp->mvn_nptr;
  237.             mtmp1 = mtmp;
  238.             mtmp = mtmp->mvn_nptr;
  239.             free(mtmp1);
  240.          }
  241.      continue;
  242.       }
  243.       else
  244.      mtmp = mtmp->mvn_nptr;
  245.     }
  246.  
  247.  
  248.     mtmp = mhead;
  249.     while (mtmp != NULL)
  250.     {
  251.       /* send OCP to our CUSM clients for our VAT-non NV clients */
  252.  
  253.       if ((find_client(mtmp->mvn_addr.addr) == NULL) && (vatinterval == 10)) 
  254.       {
  255.      if ((mtmp->mvn_spoke != 0) && ((tick_cnt - mtmp->mvn_spoke) < VAT_SPEAKER_INTERVAL))
  256.         send_vat_ocp(mtmp);
  257.       }
  258.  
  259.       mtmp = mtmp->mvn_nptr;
  260.     }
  261.  
  262.    if (vatinterval == 10)
  263.       send_vat_idlist();
  264.  
  265.     for (cnt=0; cnt<MAXCLIENT; cnt++)
  266.        if (tmp_deny_list[cnt] != 0)
  267.           if ((tmp_deny_wait[cnt] -= 1) == 0)
  268.              tmp_deny_list[cnt] = 0;
  269.  
  270.     for (cnt=0; cnt<send_to_nv_cnt; cnt++)
  271.        if (send_to_nv_timer[cnt]++ > TIMEOUT)
  272.        {
  273.       for (cnt1=cnt; cnt1<send_to_nv_cnt-1; cnt1++)
  274.       {
  275.          send_to_nv_list[cnt1] = send_to_nv_list[cnt1+1];
  276.          send_to_nv_timer[cnt1] = send_to_nv_timer[cnt1+1];
  277.       }
  278.       send_to_nv_cnt--;
  279.        }
  280. }
  281.  
  282. void my_perror(mesg)
  283.    char *mesg;
  284. {
  285.     extern char *sys_errlist[];
  286.     extern int errno;
  287.  
  288.     dolog("%s : %s: FATAL ERROR: EXITING", mesg, sys_errlist[errno]);
  289.     printf("%s : %s: FATAL ERROR: EXITING", mesg, sys_errlist[errno]);
  290.     exit(1);
  291. }
  292.  
  293. dolog(va_alist)
  294. va_dcl
  295. {
  296.     static int line_cnt = 0;
  297.     char    *fmt;
  298.     va_list args;
  299.  
  300.     if (log_limit == 0)
  301.        return;
  302.  
  303.     if (log_limit != -1)
  304.     {
  305.        if (line_cnt++ > log_limit)
  306.        {
  307.           line_cnt = 0;
  308.           fclose(log_file);
  309.           if ((log_file = fopen(tracefile,"w")) != NULL)
  310.           {
  311. #ifdef _BSD
  312.              setlinebuf(log_file);
  313. #else
  314.              setvbuf(log_file,NULL,_IOLBF,0);
  315. #endif
  316.  
  317.              dolog("open_log file: %s\n",tracefile);
  318.           }
  319.           else
  320.              log_limit = 0;
  321.        }
  322.     }
  323.  
  324.  
  325.     va_start(args);
  326.  
  327.     fmt = va_arg(args, char *);
  328.  
  329.     if (!log_file)
  330.     {
  331.         return;
  332.     }
  333.  
  334.     if (fmt && *fmt)
  335.     {
  336.         (void) vfprintf(log_file, fmt, args);
  337. #ifdef DEBUG
  338.        if (debug)
  339.           (void) vfprintf(stdout, fmt, args);
  340. #endif
  341.     }
  342.     va_end(args);
  343. }
  344.  
  345. get_my_addr(myaddr)
  346.     struct  sockaddr_in *myaddr;
  347. {
  348.     int n_interfaces, i;
  349.     char *buf;
  350.     struct ifconf ifc;
  351.     struct ifreq *ifr;
  352.     int s_in;
  353.     /*
  354.     unsigned long foo;
  355.  
  356.     bzero((caddr_t) myaddr,socksize(&ifr->ifr_addr));
  357.     foo = inet_addr("132.236.91.204");
  358.     bcopy((caddr_t) &foo, (caddr_t) &myaddr->sin_addr.s_addr, 4);
  359.     return;
  360.     */
  361.  
  362.  
  363.     if ((s_in = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
  364.     {
  365.         my_perror("if_getlist: socket");
  366.         exit(errno);
  367.     }
  368.  
  369.     ifc.ifc_len = (MAXIF * sizeof (struct ifreq)) + sizeof(int);
  370.  
  371.     if ( !(buf = malloc(ifc.ifc_len)))
  372.     {
  373.         my_perror("if_getlist: malloc");
  374.         exit(errno);
  375.     }
  376.  
  377.     ifc.ifc_buf = buf;
  378.  
  379.     if (ioctl(s_in, SIOCGIFCONF, (caddr_t) &ifc) < 0)
  380.     {
  381.         my_perror("if_getlist: ioctl(SIOCGIFCONF)");
  382.         exit(errno);
  383.     }
  384.  
  385.     n_interfaces = ifc.ifc_len / sizeof (struct ifreq);
  386.  
  387.     ifr = (struct ifreq *) ifc.ifc_buf;
  388.     for (i = 0; i < n_interfaces; i++)
  389.     {
  390.         if (ifr->ifr_addr.sa_family == AF_INET)
  391.         {
  392.            bcopy((caddr_t) &ifr->ifr_addr, (caddr_t) myaddr, socksize(&ifr->ifr_addr));
  393.            break;
  394.         }
  395.         ifr = (struct ifreq *) ((caddr_t) ifr + (sizeof(*ifr) + socksize(&ifr->ifr_addr) - sizeof (ifr->ifr_addr)));
  396.     }
  397.     (void) free(buf);
  398. }
  399.  
  400.  
  401. int get_type(vidptr,csock)
  402.     VideoPacketHeader   *vidptr;
  403.     struct sockaddr_in  csock;
  404. {
  405.     short cnt,*id;
  406.  
  407.  
  408.     for (cnt=0; cnt<restrict_cnt; cnt++)
  409.        if (restrict_list[cnt] == csock.sin_addr.s_addr)
  410.           return(CLIENT);
  411.  
  412.     for (cnt=0; cnt<bcc_srv_cnt; cnt++)
  413.        if (bcc_server_list[cnt] == csock.sin_addr.s_addr)
  414.           return(BCC_SERVER);
  415.  
  416.     for (cnt=0; cnt<bcc_clt_cnt; cnt++)
  417.        if (bcc_client_list[cnt] == csock.sin_addr.s_addr)
  418.           return(BCC_CLIENT);
  419.  
  420.     for (cnt=0; cnt<ref_ucast_cnt; cnt++)
  421.        if (ref_ucast_list[cnt] == csock.sin_addr.s_addr)
  422.           return(REF3_SERVER);
  423.  
  424.     if (vidptr->message == kBCCOpen)
  425.     {
  426.        /* 
  427.           this must be a dynamic BCC client attempting to get a feed
  428.           from us.  If there is a conference ID for dynamic BCC clients, 
  429.           make sure his is correct, also check and see how many of
  430.           these clients are already connected.
  431.        */
  432.       
  433.       if (bcc_gclient_cnt == gbcc_cnt)
  434.      return(-1);
  435.  
  436.       id = (short *) ((char *) vidptr + HEADERLEN);
  437.  
  438.       if ((gbcc_id != 0) && (gbcc_id != *id))
  439.          return(-1);
  440.  
  441.       return(BCC_GCLIENT);
  442.  
  443.     }
  444.  
  445.     if (restrict_cnt != 0)
  446.        return(-1);
  447.     
  448.     return(CLIENT);
  449. }
  450.  
  451.  
  452. short deny(csock)
  453.     struct sockaddr_in  csock;
  454. {
  455.     short cnt;
  456.  
  457.     for (cnt=0; cnt<deny_cnt; cnt++)
  458.        if (deny_list[cnt] == csock.sin_addr.s_addr)
  459.           return(1);
  460.  
  461.     for (cnt=0; cnt<MAXCLIENT; cnt++)
  462.        if (tmp_deny_list[cnt] == csock.sin_addr.s_addr)
  463.           return(1);
  464.  
  465.     return(0);
  466. }
  467.  
  468.  
  469. tmp_deny(who,time)
  470.    unsigned long who;
  471.    int time;
  472.  
  473. {
  474.     struct in_addr in;
  475.     short cnt;
  476.  
  477.     for (cnt=0; cnt<MAXCLIENT; cnt++)
  478.        if (tmp_deny_list[cnt] == 0)
  479.           break;
  480.  
  481.     if (tmp_deny_list[cnt] != 0)
  482.     {
  483.        in.s_addr = who;
  484.        dolog("Unable to add %s to the temporary deny list\n",inet_ntoa(in));
  485.     }
  486.  
  487.     tmp_deny_list[cnt] = who;
  488.     tmp_deny_wait[cnt] = time;
  489. }
  490.